﻿using System;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using ITViet.Domains;
using ITViet.Services;
using Library.Logging;
using System.IO;

namespace ITViet.Web.App_Code
{
  public class AdminBasePage : Page
  {
    private XmlDataSource m_xmlData;

    #region Override Base
    protected override void OnError(EventArgs e)
    {
      Exception ex = Server.GetLastError();
      Logger.LogError("AdminBasePage::OnError.", ex, DefaultLoggingCategory, null);
    }

    protected override void OnLoad(EventArgs e)
    {
      // Intentionally pauses server-side processing, to demonstrate the Loading Panel functionality.
      if (IsCallback)
        System.Threading.Thread.Sleep(100);

      string curUrl = Request.Url.AbsoluteUri.ToLower();
      if (RequiredPermission == -1)
      {
        CanView = CanApprove = CanDelete = CanModify = true;
      }
      else
      {
        CanView = HasPermission(RequiredPermission);
      }
      base.OnLoad(e);

    }

    protected override void OnInit(EventArgs e)
    {
      string curUrl = Request.Url.AbsoluteUri.ToLower();
      base.OnInit(e);
      if (!Page.IsCallback)
      {
        if (CurrentUser == null && !curUrl.Contains("login.aspx"))
        {
          Response.Redirect(GetUrlLogin());
        }
      }
    }

    protected void Page_PreInit(object sender, EventArgs e)
    {
      string themeName = GlobalCache.Instance.Themes;
      this.Theme = themeName;
    }

    protected override void InitializeCulture()
    {
      base.InitializeCulture();
      LoadLanguage(CurrentLanguage);
    }

    public void SetPageLanguage(Language lang)
    {
      LoadLanguage(lang);
      Response.Redirect(Request.Url.AbsoluteUri);
    }

    private void LoadLanguage(Language lang)
    {
      CurrentLanguage = lang;
      Page.Culture = CurrentLanguage.Culture;
      Page.UICulture = CurrentLanguage.Culture;
    }
    #endregion

    #region Properties
    public int KeyId
    {
      get
      {
        string id = Request.QueryString["id"];
        if (String.IsNullOrEmpty(id)) return 0;
        return int.Parse(id);
      }
    }

    public int? TypeId
    {
      get
      {
        string tid = Request.QueryString["tid"];
        if (String.IsNullOrEmpty(tid)) return null;
        return int.Parse(tid);
      }
    }


    internal Language CurrentLanguage
    {
      set { Session["Language"] = value; }
      get
      {
        if (Session["Language"] == null)
          Session["Language"] = new LanguageService().GetById(GlobalCache.Instance.DefaultLanguage);
        return (Language)Session["Language"];
      }
    }

    internal User CurrentUser
    {
      get
      {
        //Domains.User user = new UserService().GetByUsername("cong");
        //Session["CurrentUser"] = user;
        return Session["CurrentUser"] as Domains.User;
      }
      set { Session["CurrentUser"] = value; }
    }

    internal TList<GroupPermission> CurrentUserPermission
    {
      get { return Session["CurrentUserPermission"] as TList<GroupPermission>; }
      set { Session["CurrentUserPermission"] = value; }
    }

    internal string ErrorMessage
    {
      get { return Session["ErrorMessage"] as string; }
      set { Session["ErrorMessage"] = value; }
    }

    public string SelectedMenuItem
    {
      set
      {
        Session["SelectedMenuItem"] = value;
      }
      get
      {
        if (Session["SelectedMenuItem"] == null)
        {
          return null;
        }
        return (string)Session["SelectedMenuItem"];
      }
    }

    public string SelectedMenuItemTitle
    {
      set
      {
        Session["SelectedMenuItemTitle"] = value;
      }
      get
      {
        if (Session["SelectedMenuItemTitle"] == null)
        {
          return null;
        }
        return (string)Session["SelectedMenuItemTitle"];
      }
    }

    public string SelectedSubMenuItem
    {
      set
      {
        Session["SelectedSubMenuItem"] = value;
      }
      get
      {
        if (Session["SelectedSubMenuItem"] == null)
        {
          return null;
        }
        return (string)Session["SelectedSubMenuItem"];
      }
    }

    public string SelectedSubMenuItemTitle
    {
      set
      {
        Session["SelectedSubMenuItemTitle"] = value;
      }
      get
      {
        if (Session["SelectedSubMenuItemTitle"] == null)
        {
          return null;
        }
        return (string)Session["SelectedSubMenuItemTitle"];
      }
    }

    public int SelectedMenuItemIndex
    {
      set
      {
        Session["SelectedMenuItemIndex"] = value;
      }
      get
      {
        if (Session["SelectedMenuItemIndex"] == null)
        {
          return 0;
        }
        return (int)Session["SelectedMenuItemIndex"];
      }
    }

    public string LocalPath
    {
      get { return Server.MapPath("~/" + PostedDirectory + "/"); }
    }

    private string m_postedDirectory = "App_Temp";
    public string PostedDirectory
    {
      get { return m_postedDirectory; }
      set { m_postedDirectory = value; }
    }

    public const string DefaultLoggingCategory = "General";

    public string XmlStatusFile
    {
      get
      {
        string culture = (!string.IsNullOrEmpty(CurrentLanguage.Culture)) ? "." + CurrentLanguage.Culture : "";
        return "~/App_Data/Status" + culture + ".xml";
      }
    }

    public string XmlMainMenuFile
    {
      get
      {
        string culture = (!string.IsNullOrEmpty(CurrentLanguage.Culture)) ? "." + CurrentLanguage.Culture : "";
        return "~/App_Data/AdminMainMenu" + culture + ".xml";
      }
    }

    public string XmlSubMenuFile
    {
      get
      {
        string culture = (!string.IsNullOrEmpty(CurrentLanguage.Culture)) ? "." + CurrentLanguage.Culture : "";
        return "~/App_Data/AdminSubMenu" + culture + ".xml";
      }
    }

    private bool m_canApprove = false;
    public bool CanApprove
    {
      get { return m_canApprove; }
      set { m_canApprove = value; }
    }
    private bool m_canModify = false;
    public bool CanModify
    {
      get { return m_canModify; }
      set { m_canModify = value; }
    }
    private bool m_canDetele = false;
    public bool CanDelete
    {
      get { return m_canDetele; }
      set { m_canDetele = value; }
    }
    private bool m_canView = false;
    public bool CanView
    {
      get { return m_canView; }
      set { m_canView = value; }
    }

    #endregion

    #region Need To Override
    protected virtual void ApplyAction()
    { }

    internal virtual int RequiredPermission
    {
      get { return -1; }
    }

    internal virtual void SetPermission()
    {

    }

    public XmlDataSource XmlData
    {
      get { return m_xmlData; }
      set { m_xmlData = value; }
    }

    
    #endregion

    #region Public Methods
    public void CreateAuthenticationTicket(string username)
    {
      FormsAuthentication.SetAuthCookie(username, false);
      FormsAuthenticationTicket clientTicket =
      new FormsAuthenticationTicket(1,
                                      username,
                                      DateTime.Now,
                                      DateTime.Now.AddMinutes(Session.Timeout + 1),
                                      false,
                                      "Agent");
      HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(clientTicket));
      Response.Cookies.Add(cookie);
    }

    public void ClearAuthenticationTicket()
    {
      FormsAuthentication.SignOut();
      Session.Clear();
    }

    public void WriteLog(string description, Exception ex)
    {
      Logger.LogError(description, ex, DefaultLoggingCategory, null);
    }

    public void ClearSession(string[] ssName)
    {
      if (ssName == null)
        return;
      for (int i = 0; i < ssName.Length; i++)
        Session[ssName[i]] = null;
    }

    /// <summary>
    /// Create directory for upload file
    /// </summary>
    /// <param name="configPath"></param>
    /// <param name="relativePath"></param>
    /// <returns></returns>
    public string CreateDir(string configPath, out string relativePath)
    {
      relativePath = string.Empty;
      try
      {
        string directory = configPath + DateTime.Now.Day.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Year.ToString() + "/";
        string absolutePath = "~/" + directory;
        absolutePath = Server.MapPath(absolutePath);
        if (!Directory.Exists(absolutePath))
        {
          Directory.CreateDirectory(absolutePath);
        }
        relativePath = "../" + directory;
        return absolutePath;
      }
      catch (Exception ex)
      {
        WriteLog("Create New Directory", ex);
        return string.Empty;
      }
    }

    public string CreateHtmlEditorUploadDir(string configPath, string subFolder)
    {
      try
      {
        string directory;
        if (!string.IsNullOrEmpty(subFolder))
        {
          directory = configPath + subFolder + "/" + DateTime.Now.Day.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Year.ToString() + "/";
        }
        else
        {
          directory = configPath;
        }
        string absolutePath = "~/" + directory;
        string temp = Server.MapPath(absolutePath);
        if (!Directory.Exists(temp))
        {
          Directory.CreateDirectory(temp);
        }
        return absolutePath;
      }
      catch (Exception ex)
      {
        WriteLog("Create New Directory", ex);
        return string.Empty;
      }
    }

    public string GetSubMenuSelectedTitle()
    {
      string title = string.Empty;
      string culture = (!string.IsNullOrEmpty(CurrentLanguage.Culture)) ? "." + CurrentLanguage.Culture : "";
      string dataFile = "~/App_Data/AdminSubMenu" + culture + ".xml";
      string xpath = "Menus/Groups/Brand/Item[@Id='" + TypeId + "']";
      XmlDataSource dsData = new XmlDataSource();
      dsData.DataFile = dataFile;
      XmlNode xmlNode = dsData.GetXmlDocument().SelectSingleNode(xpath);
      if (xmlNode != null)
        title = xmlNode.Attributes["Title"].Value;
      return title;
    }

    public string GetItemDescription(object status, string path)
    {
      if (m_xmlData == null)
        m_xmlData = GetStatusXmlData(path);
      XmlNode node = m_xmlData.GetXmlDocument().SelectSingleNode(path + "[@Id='" + status + "']");
      return node != null ? node.Attributes["Value"].Value : "";
    }

    public string FormatDate(object date)
    {
      DateTime value = DateTime.MinValue;
      DateTime.TryParse(date.ToString(), out value);
      return value > DateTime.MinValue ? value.ToString() : "";
    }

    public string ParseHtml(object text)
    {
      if (text == null || text == DBNull.Value) return string.Empty;
      return Utils.SafeHtmlString(text.ToString());
    }

    public string GetUrlLogin()
    {
      string url = "Login.aspx?Returnurl=" + Request.Url.AbsolutePath + "?";
      if (Request.QueryString.Count > 0)
      {
        for (int i = 0; i < Request.QueryString.Count; i++)
        {
          url += "&" + Request.QueryString.GetKey(i) + "=" + Request.QueryString[i];
        }
      }
      return url;
    }

    public bool HasPermission(int functionId)
    {
      if (functionId == 0)
      {
        CanModify = true;
        CanDelete = true;
        CanApprove = true;
        return true;
      }


      GroupPermission permission = CurrentUserPermission.Find(delegate(GroupPermission p)
      {
        return p.FunctionId == functionId;
      });

      if (permission != null)
      {
        CanModify = Convert.ToBoolean(permission.Permission & PermissionValue.Modify);
        CanDelete = Convert.ToBoolean(permission.Permission & PermissionValue.Delete);
        CanApprove = Convert.ToBoolean(permission.Permission & PermissionValue.Approve);
        return Convert.ToBoolean(permission.Permission & PermissionValue.View);
      }
      CanModify = false;
      CanDelete = false;
      CanApprove = false;
      return false;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="vnDataFile"></param>
    /// <param name="usDataFile"></param>
    /// <param name="xmlPath"></param>
    /// <returns></returns>
    public XmlDataSource GetXmlDataSource(string vnDataFile, string usDataFile, string xmlPath)
    {
      XmlDataSource dsData = new XmlDataSource();
      if (CurrentLanguage.Id == (int)LanguageList.Vietnamese)
        dsData.DataFile = vnDataFile;
      else if (CurrentLanguage.Id == (int)LanguageList.English)
        dsData.DataFile = usDataFile;
      dsData.XPath = xmlPath;
      return dsData;
    }

    public XmlDataSource GetStatusXmlData(string xmlPath)
    {
      return GetXmlDataSource("~/App_Data/Status.vi-VN.xml", "~/App_Data/Status.xml", xmlPath);
    }

    public DataTable GetSubMenuName(string[] pathList)
    {
      DataTable tbl = new DataTable();
      tbl.Columns.Add(new DataColumn("Id", Type.GetType("System.Int32")));
      tbl.Columns.Add(new DataColumn("Text", Type.GetType("System.String")));
      if (pathList == null) return null;
      XmlDataSource dsData = new XmlDataSource();
      dsData.DataFile = XmlSubMenuFile;
      foreach (string xmlPath in pathList)
      {
        XmlNode xmlNode = dsData.GetXmlDocument().SelectSingleNode(xmlPath);
        if (xmlNode != null)
        {
          int id = (xmlNode.Attributes["Id"] != null) ? Convert.ToInt32(xmlNode.Attributes["Id"]) : 0;
          string text = (xmlNode.Attributes["Text"] != null) ? xmlNode.Attributes["Text"].ToString() : string.Empty;
          DataRow row = tbl.NewRow();
          row["Id"] = id;
          row["Text"] = text;
          tbl.Rows.Add(row);
        }
      }
      return tbl;
    }

    #endregion
  }
}
